using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace GenerativeAgents.Core
{
    /// <summary>
    /// 事件处理器
    /// 负责将原始事件转换为完整的智能体事件
    /// </summary>
    public class EventProcessor : MonoBehaviour
    {
        [Header("处理配置")]
        [SerializeField] private bool enableEventLogging = false;
        [SerializeField] private int maxKeywordsPerEvent = 5;
        [SerializeField] private float defaultPoignancyScore = 3f;
        
        // 事件处理统计
        private int processedEventCount = 0;
        private int failedEventCount = 0;
        private Dictionary<EventType, int> eventTypeStats;
        
        private void Awake()
        {
            InitializeProcessor();
        }
        
        private void InitializeProcessor()
        {
            eventTypeStats = new Dictionary<EventType, int>();
            foreach (EventType eventType in Enum.GetValues(typeof(EventType)))
            {
                eventTypeStats[eventType] = 0;
            }
        }
        
        /// <summary>
        /// 处理原始事件，转换为AgentEvent
        /// </summary>
        public AgentEvent ProcessRawEvent(RawEvent rawEvent, IEmbeddingEngine embeddingEngine, ILanguageModel languageModel)
        {
            try
            {
                // 创建基础AgentEvent
                var agentEvent = CreateBaseAgentEvent(rawEvent);
                
                // 生成详细描述
                agentEvent.description = GenerateEventDescription(rawEvent);
                
                // 生成嵌入向量
                if (embeddingEngine != null)
                {
                    agentEvent.embedding = embeddingEngine.GenerateEmbedding(agentEvent.description);
                }
                else
                {
                    agentEvent.embedding = new float[256]; // 默认维度
                }
                
                // 评估重要性
                if (languageModel != null)
                {
                    agentEvent.poignancy = languageModel.ScoreImportance(agentEvent.description);
                }
                else
                {
                    agentEvent.poignancy = CalculateDefaultImportance(rawEvent);
                }
                
                // 提取关键词
                if (languageModel != null)
                {
                    agentEvent.keywords = languageModel.ExtractKeywords(agentEvent.description, maxKeywordsPerEvent);
                }
                else
                {
                    agentEvent.keywords = ExtractDefaultKeywords(agentEvent.description);
                }
                
                // 设置参与者
                agentEvent.participants = ExtractParticipants(rawEvent);
                
                // 设置位置名称
                agentEvent.locationName = DetermineLocationName(rawEvent.location);
                
                // 设置事件优先级
                agentEvent.priority = DetermineEventPriority(agentEvent);
                
                // 验证事件
                if (ValidateAgentEvent(agentEvent))
                {
                    processedEventCount++;
                    eventTypeStats[agentEvent.eventType]++;
                    
                    if (enableEventLogging)
                    {
                        Debug.Log($"[EventProcessor] Processed event: {agentEvent.description} (Importance: {agentEvent.poignancy})");
                    }
                    
                    return agentEvent;
                }
                else
                {
                    failedEventCount++;
                    Debug.LogWarning($"[EventProcessor] Event validation failed: {rawEvent.id}");
                    return null;
                }
            }
            catch (Exception ex)
            {
                failedEventCount++;
                Debug.LogError($"[EventProcessor] Error processing event {rawEvent.id}: {ex.Message}");
                return null;
            }
        }
        
        /// <summary>
        /// 创建基础AgentEvent
        /// </summary>
        private AgentEvent CreateBaseAgentEvent(RawEvent rawEvent)
        {
            var agentEvent = new AgentEvent
            {
                eventId = rawEvent.id,
                subject = rawEvent.subject,
                predicate = rawEvent.predicate,
                objectEntity = rawEvent.objectEntity,
                location = rawEvent.location,
                timestamp = rawEvent.timestamp,
                eventType = rawEvent.type,
                metadata = new Dictionary<string, object>(rawEvent.metadata)
            };
            
            // 设置对话相关属性
            if (rawEvent.type == EventType.Conversation && rawEvent.metadata.ContainsKey("conversationId"))
            {
                agentEvent.isConversation = true;
                agentEvent.conversationId = rawEvent.metadata["conversationId"].ToString();
            }
            
            return agentEvent;
        }
        
        /// <summary>
        /// 生成事件描述
        /// </summary>
        private string GenerateEventDescription(RawEvent rawEvent)
        {
            var description = $"{rawEvent.subject} {rawEvent.predicate} {rawEvent.objectEntity}";
            
            // 根据事件类型添加上下文信息
            switch (rawEvent.type)
            {
                case EventType.Movement:
                    description = EnhanceMovementDescription(rawEvent, description);
                    break;
                    
                case EventType.Conversation:
                    description = EnhanceConversationDescription(rawEvent, description);
                    break;
                    
                case EventType.Interaction:
                    description = EnhanceInteractionDescription(rawEvent, description);
                    break;
                    
                case EventType.Observation:
                    description = EnhanceObservationDescription(rawEvent, description);
                    break;
            }
            
            // 添加时间和位置信息
            description += $" at {rawEvent.timestamp:HH:mm} in {DetermineLocationName(rawEvent.location)}";
            
            return description;
        }
        
        /// <summary>
        /// 增强移动事件描述
        /// </summary>
        private string EnhanceMovementDescription(RawEvent rawEvent, string baseDescription)
        {
            if (rawEvent.metadata.ContainsKey("distance"))
            {
                var distance = (float)rawEvent.metadata["distance"];
                if (distance > 5f)
                {
                    baseDescription += " (long distance)";
                }
                else if (distance < 1f)
                {
                    baseDescription += " (short distance)";
                }
            }
            
            return baseDescription;
        }
        
        /// <summary>
        /// 增强对话事件描述
        /// </summary>
        private string EnhanceConversationDescription(RawEvent rawEvent, string baseDescription)
        {
            if (rawEvent.metadata.ContainsKey("participants"))
            {
                var participants = rawEvent.metadata["participants"] as List<string>;
                if (participants != null && participants.Count > 2)
                {
                    baseDescription += " (group conversation)";
                }
            }
            
            return baseDescription;
        }
        
        /// <summary>
        /// 增强交互事件描述
        /// </summary>
        private string EnhanceInteractionDescription(RawEvent rawEvent, string baseDescription)
        {
            if (rawEvent.metadata.ContainsKey("interactionType"))
            {
                var interactionType = rawEvent.metadata["interactionType"].ToString();
                baseDescription += $" ({interactionType})";
            }
            
            return baseDescription;
        }
        
        /// <summary>
        /// 增强观察事件描述
        /// </summary>
        private string EnhanceObservationDescription(RawEvent rawEvent, string baseDescription)
        {
            // 观察事件通常包含更多上下文
            return baseDescription + " (observed behavior)";
        }
        
        /// <summary>
        /// 计算默认重要性分数
        /// </summary>
        private int CalculateDefaultImportance(RawEvent rawEvent)
        {
            int importance = 3; // 基础分数
            
            // 基于事件类型调整
            switch (rawEvent.type)
            {
                case EventType.Conversation:
                    importance = 4;
                    break;
                case EventType.Interaction:
                    importance = 3;
                    break;
                case EventType.Movement:
                    importance = 2;
                    break;
                case EventType.Observation:
                    importance = 2;
                    break;
            }
            
            // 基于参与者数量调整
            if (rawEvent.metadata.ContainsKey("participants"))
            {
                var participants = rawEvent.metadata["participants"] as List<string>;
                if (participants != null && participants.Count > 2)
                {
                    importance += 1; // 多人事件更重要
                }
            }
            
            // 基于距离调整（对移动事件）
            if (rawEvent.type == EventType.Movement && rawEvent.metadata.ContainsKey("distance"))
            {
                var distance = (float)rawEvent.metadata["distance"];
                if (distance > 10f)
                {
                    importance += 1; // 长距离移动更重要
                }
            }
            
            return Mathf.Clamp(importance, 1, 10);
        }
        
        /// <summary>
        /// 提取默认关键词
        /// </summary>
        private List<string> ExtractDefaultKeywords(string description)
        {
            var keywords = new List<string>();
            
            if (string.IsNullOrEmpty(description))
                return keywords;
            
            // 简单的关键词提取
            var words = description.ToLower()
                .Split(new char[] { ' ', '.', ',', '!', '?', ':', ';' }, StringSplitOptions.RemoveEmptyEntries);
            
            var stopWords = new HashSet<string> 
            { 
                "the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for", 
                "of", "with", "by", "is", "was", "are", "were", "be", "been", "have", 
                "has", "had", "do", "does", "did", "will", "would", "could", "should" 
            };
            
            var wordFreq = new Dictionary<string, int>();
            foreach (var word in words)
            {
                if (word.Length > 2 && !stopWords.Contains(word))
                {
                    wordFreq[word] = wordFreq.GetValueOrDefault(word, 0) + 1;
                }
            }
            
            // 选择频率最高的词作为关键词
            keywords = wordFreq
                .OrderByDescending(kv => kv.Value)
                .Take(maxKeywordsPerEvent)
                .Select(kv => kv.Key)
                .ToList();
            
            return keywords;
        }
        
        /// <summary>
        /// 提取参与者
        /// </summary>
        private List<string> ExtractParticipants(RawEvent rawEvent)
        {
            var participants = new List<string>();
            
            // 添加主语
            if (!string.IsNullOrEmpty(rawEvent.subject) && rawEvent.subject != "someone")
            {
                participants.Add(rawEvent.subject);
            }
            
            // 从元数据中提取参与者
            if (rawEvent.metadata.ContainsKey("participants"))
            {
                var metaParticipants = rawEvent.metadata["participants"] as List<string>;
                if (metaParticipants != null)
                {
                    foreach (var participant in metaParticipants)
                    {
                        if (!participants.Contains(participant))
                        {
                            participants.Add(participant);
                        }
                    }
                }
            }
            
            // 从宾语中提取（对于对话事件）
            if (rawEvent.type == EventType.Conversation && !string.IsNullOrEmpty(rawEvent.objectEntity))
            {
                // 尝试从"说话对象"格式中提取名字
                var objectParts = rawEvent.objectEntity.Split(':');
                if (objectParts.Length > 0)
                {
                    var targetName = objectParts[0].Trim();
                    if (!participants.Contains(targetName))
                    {
                        participants.Add(targetName);
                    }
                }
            }
            
            return participants;
        }
        
        /// <summary>
        /// 确定位置名称
        /// </summary>
        private string DetermineLocationName(Vector3 location)
        {
            // 尝试通过位置查找空间节点
            // 这里需要与空间记忆系统集成
            // 目前使用简化的实现
            
            return $"location_{Mathf.RoundToInt(location.x)}_{Mathf.RoundToInt(location.z)}";
        }
        
        /// <summary>
        /// 确定事件优先级
        /// </summary>
        private EventPriority DetermineEventPriority(AgentEvent agentEvent)
        {
            if (agentEvent.poignancy >= 8)
                return EventPriority.Critical;
            else if (agentEvent.poignancy >= 6)
                return EventPriority.High;
            else if (agentEvent.poignancy >= 3)
                return EventPriority.Normal;
            else
                return EventPriority.Low;
        }
        
        /// <summary>
        /// 验证AgentEvent
        /// </summary>
        private bool ValidateAgentEvent(AgentEvent agentEvent)
        {
            // 基本验证
            if (string.IsNullOrEmpty(agentEvent.eventId))
                return false;
            
            if (string.IsNullOrEmpty(agentEvent.description))
                return false;
            
            if (agentEvent.poignancy < 1 || agentEvent.poignancy > 10)
                return false;
            
            if (agentEvent.embedding == null || agentEvent.embedding.Length == 0)
                return false;
            
            // 事件类型特定验证
            switch (agentEvent.eventType)
            {
                case EventType.Conversation:
                    if (agentEvent.isConversation && string.IsNullOrEmpty(agentEvent.conversationId))
                        return false;
                    break;
            }
            
            return true;
        }
        
        /// <summary>
        /// 批量处理事件
        /// </summary>
        public List<AgentEvent> ProcessRawEvents(List<RawEvent> rawEvents, IEmbeddingEngine embeddingEngine, ILanguageModel languageModel)
        {
            var processedEvents = new List<AgentEvent>();
            
            foreach (var rawEvent in rawEvents)
            {
                var agentEvent = ProcessRawEvent(rawEvent, embeddingEngine, languageModel);
                if (agentEvent != null)
                {
                    processedEvents.Add(agentEvent);
                }
            }
            
            return processedEvents;
        }
        
        /// <summary>
        /// 获取处理统计信息
        /// </summary>
        public string GetProcessingStats()
        {
            var stats = $"Processed: {processedEventCount}, Failed: {failedEventCount}\n";
            stats += "Event Types:\n";
            
            foreach (var kvp in eventTypeStats)
            {
                if (kvp.Value > 0)
                {
                    stats += $"  {kvp.Key}: {kvp.Value}\n";
                }
            }
            
            return stats;
        }
        
        /// <summary>
        /// 重置统计信息
        /// </summary>
        public void ResetStats()
        {
            processedEventCount = 0;
            failedEventCount = 0;
            
            foreach (var key in eventTypeStats.Keys.ToList())
            {
                eventTypeStats[key] = 0;
            }
        }
        
        /// <summary>
        /// 设置处理参数
        /// </summary>
        public void SetProcessingParameters(int maxKeywords, float defaultPoignancy, bool enableLogging)
        {
            maxKeywordsPerEvent = maxKeywords;
            defaultPoignancyScore = defaultPoignancy;
            enableEventLogging = enableLogging;
        }
    }
}